// Created by Joe on 2017/7/14.

app.controller(
    'NewsController',
    [
        'KEY', 'config', '$scope', '$location', '$timeout', '$sce', 'UserService', 'NewsService',
        function (KEY, config, $scope, $location, $timeout, $sce, UserService, NewsService) {
            init();

            function init() {
                // animate switch
                $.fx.off = config.forbiddenAnimate;

                // image url, may be changed
                $scope.imgUrl = 'https://www.icity24.xyz/icity/s';

                // set page
                $scope.page = ['home', 'detail'];
                $scope.limit = {theme: 3, list: 5, step: 200, height: 720 - config.borderMask};
                $scope.panel = {height: 0, top: 0, empty: false, load: false, listLoaded: false};
                $scope.control = {
                    page: 0,
                    theme: 0, themeIndex: 0, tb: -1,
                    list: 0, listIndex: -1,
                    la: 1, ra: 1,
                    // request index
                    id: 0
                };

                // set selector
                $scope.selector = {
                    $news: $('.scroll'),
                    $newsContent: $('.city__news-center .content')
                };

                // set timer
                $scope.timer = null;

                // set data
                $scope.data = {
                    // request index compare
                    id: 0,
                    theme: [],
                    curTheme: [],
                    list: [],
                    curList: [],
                    detail: {}
                };

                // set cache
                $scope.cache = {list: {}};

                // add logic
                addLogic();

                // get info
                $scope.panel.load = true;
                NewsService.getNewsType()
                    .then(function (info) {
                        $scope.data.theme = info;

                        $scope.data.curTheme = $scope.data.theme.slice(
                            $scope.control.theme, $scope.control.theme + $scope.limit.theme
                        );

                        $scope.getNewsList(true);
                        // $scope.panel.load = false;
                    });

                // ele action
                $scope.move = function (evt, cb) {
                    event.preventDefault();
                    if ($scope.control.page === 1) return;
                    switch (evt.keyCode) {
                        case KEY.UP:
                            moveShim('up');
                            break;
                        case KEY.DOWN:
                            moveShim('down');
                            break;
                        case KEY.LEFT:
                            moveShim('left');
                            break;
                        case KEY.RIGHT:
                            moveShim('right');
                            break;
                        case KEY.ENTER:
                            cb instanceof Function && cb();
                            break;
                    }
                };

                // global action
                document.addEventListener('keydown', globalAction);
                document.addEventListener('keyup', arrowAction);
            }

            function addLogic() {
                // get list
                $scope.getNewsList = function (first) {
                    var type = $scope.data.curTheme[$scope.control.themeIndex]['type'];
                    // fetch cache
                    if ($scope.cache.list[type]) {
                        $scope.panel.load = false;
                        $scope.control.list = 0;
                        $scope.control.listIndex = -1;
                        $scope.data.list = $scope.cache.list[type].info;
                        $scope.cache.list[type].id = $scope.control.id++;
                        $scope.data.curList = $scope.data.list.slice(
                            $scope.control.list, $scope.control.list + $scope.limit.list
                        );
                        $scope.panel.empty = $scope.data.list.length === 0;
                        return;
                    }
                    // http request
                    $timeout.cancel($scope.timer);
                    $scope.timer = $timeout(function () {
                        $scope.data.list = [];
                        $scope.data.curList = [];
                        $scope.control.list = 0;
                        $scope.control.listIndex = -1;
                        $scope.panel.empty = false;
                        $scope.panel.load = true;
                        NewsService.getNewsList(type, $scope.control.id++, type)
                            .then(function (result) {
                                $scope.panel.listLoaded = true;
                                if (!$scope.cache.list[type]) $scope.cache.list[type] = result;
                                if ($scope.control.id === result.id + 1) {
                                    $scope.data.list = result.info;
                                    $scope.data.curList = $scope.data.list.slice(
                                        $scope.control.list, $scope.control.list + $scope.limit.list
                                    );
                                    $scope.panel.load = false;
                                    $scope.panel.empty = $scope.data.list.length === 0;
                                }
                            })
                    }, first ? 0 : config.requestDelay);
                };

                // show list
                $scope.showList = function () {
                    pageSwitch(0);
                    $scope.data.detail = {};
                };

                // show detail
                $scope.showDetail = function () {
                    $scope.control.page === 0 && pageSwitch(1);
                    arrowSwitch();
                    $timeout.cancel($scope.timer);
                    $scope.timer = $timeout(function () {
                        // though content has been loaded, image also need request
                        // so, add request delay here to optimize performance
                        var curListItem = $scope.data.curList[$scope.control.listIndex];
                        $scope.data.detail = {
                            title: curListItem.title,
                            createTime: curListItem.createTime,
                            content: $sce.trustAsHtml(curListItem.content)
                        };
                        $timeout(function () {
                            $scope.panel.height = parseInt($scope.selector.$newsContent.css('height'), 10) + 205;
                        });
                        $scope.panel.top = 0;
                        $scope.selector.$news.css('top', 0);
                    }, config.requestDelay);
                };
            }

            function pageSwitch(page) {
                page = page || 0;
                $scope.control.page = page;
            }

            function arrowSwitch(dir, state) {
                if ($scope.control.list === 0 && $scope.control.listIndex === 0) {
                    $scope.control.la = 0;
                } else {
                    $scope.control.la = 1;
                }

                if ($scope.control.list + $scope.control.listIndex === $scope.data.list.length - 1) {
                    $scope.control.ra = 0;
                } else {
                    $scope.control.ra = 1;
                }

                if (dir === 'left') {
                    if ($scope.control.la === 0) {
                        return;
                    } else if (state === 'focus') {
                        $scope.control.la = 2;
                    } else if (state === 'show') {
                        $scope.control.la = 1;
                    }
                }

                if (dir === 'right') {
                    if ($scope.control.ra === 0) {
                        return;
                    } else if (state === 'focus') {
                        $scope.control.ra = 2;
                    } else if (state === 'show') {
                        $scope.control.ra = 1;
                    }
                }
            }

            function moveShim(dir, type) {
                type = type || document.activeElement.id.split('-')[0];
                if (type === 'nt') {
                    // theme
                    switch (dir) {
                        case 'up':
                            if ($scope.control.themeIndex > 0) {
                                $scope.control.themeIndex--;
                                $scope.getNewsList();
                            } else if ($scope.control.theme > 0) {
                                $scope.data.curTheme = $scope.data.theme.slice(
                                    --$scope.control.theme, $scope.control.theme + $scope.limit.theme
                                );
                                $scope.getNewsList();
                            }
                            break;
                        case 'down':
                            if ($scope.control.themeIndex < $scope.limit.theme - 1) {
                                $scope.control.themeIndex++;
                                $scope.getNewsList();
                            } else if ($scope.control.theme + $scope.limit.theme < $scope.data.theme.length) {
                                $scope.data.curTheme = $scope.data.theme.slice(
                                    ++$scope.control.theme, $scope.control.theme + $scope.limit.theme
                                );
                                $scope.getNewsList();
                            }
                            break;
                        case 'right':
                            // if loading, forbidden right move
                            if (!$scope.panel.load && $scope.data.list.length > 0) {
                                if ($scope.control.listIndex === -1) {
                                    $scope.control.listIndex = 0;
                                } else {
                                    $('#nt-' + $scope.control.themeIndex).blur();
                                    $('#nl-' + $scope.control.listIndex).focus();
                                }
                                $scope.control.tb = $scope.control.themeIndex;
                            }
                            break;
                    }
                }

                if (type === 'nl') {
                    // list
                    switch (dir) {
                        case 'up':
                            if ($scope.control.listIndex > 0) {
                                $scope.control.listIndex--;
                            } else if ($scope.control.list > 0) {
                                $scope.data.curList = $scope.data.list.slice(
                                    --$scope.control.list, $scope.control.list + $scope.limit.list
                                );
                            }
                            break;
                        case 'down':
                            if ($scope.control.listIndex < $scope.limit.list - 1) {
                                $scope.control.listIndex++;
                            } else if ($scope.control.list + $scope.limit.list < $scope.data.list.length) {
                                $scope.data.curList = $scope.data.list.slice(
                                    ++$scope.control.list, $scope.control.list + $scope.limit.list
                                );
                            }
                            break;
                        case 'left':
                            $('#nl-' + $scope.control.listIndex).blur();
                            $('#nt-' + $scope.control.themeIndex).focus();
                            $scope.control.tb = -1;
                            break;
                    }
                }
            }

            function globalAction() {
                var up = function () {
                    if ($scope.control.page === 0) return;

                    if ($scope.panel.top < 0) {
                        $scope.panel.top += $scope.limit.step;
                        // top align
                        $scope.panel.top = $scope.panel.top < 0 ? $scope.panel.top : 0;
                        $scope.selector.$news.stop().animate({top: $scope.panel.top}, {duration: config.animateDelay});
                    }
                };
                var down = function () {
                    if ($scope.control.page === 0) return;

                    // eliminate image loading effect
                    $scope.panel.height = parseInt($scope.selector.$newsContent.css('height'), 10) + 205;
                    if ($scope.limit.height - $scope.panel.top < $scope.panel.height) {
                        $scope.panel.top -= $scope.limit.step;
                        // bottom align
                        $scope.panel.top = $scope.limit.height - $scope.panel.top < $scope.panel.height ?
                            $scope.panel.top : $scope.limit.height - $scope.panel.height;
                        $scope.selector.$news.stop().animate({top: $scope.panel.top}, {duration: config.animateDelay});
                    }
                };
                var left = function () {
                    if ($scope.control.page === 0) return;
                    moveShim('up', 'nl');
                    $scope.showDetail();
                    arrowSwitch('left', 'focus');
                };
                var right = function () {
                    if ($scope.control.page === 0) return;
                    moveShim('down', 'nl');
                    $scope.showDetail();
                    arrowSwitch('right', 'focus');
                };
                var back = function () {
                    if ($scope.control.page === 0) {
                        $scope.$apply(function () {
                            $location.path('/home').replace();
                        });
                    } else {
                        $scope.showList();
                    }
                };

                switch (event.keyCode) {
                    case KEY.UP:
                        up();
                        break;
                    case KEY.DOWN:
                        down();
                        break;
                    case KEY.LEFT:
                        left();
                        break;
                    case KEY.RIGHT:
                        right();
                        break;
                    case KEY.BACK:
                        back();
                        break;
                }

                $scope.$digest();
            }

            function arrowAction() {
                switch (event.keyCode) {
                    case KEY.LEFT:
                        arrowSwitch('left', 'show');
                        break;
                    case KEY.RIGHT:
                        arrowSwitch('right', 'show');
                        break;
                }

                $scope.$digest();
            }

            $scope.$on('$destroy', function () {
                $timeout.cancel($scope.timer);
                document.removeEventListener('keydown', globalAction);
                document.removeEventListener('keyup', arrowAction);
            });
        }
    ]
);